import * as THREE from "three";//引入threejs
// import { DRACOExporter, GLTFLoader } from 'three/examples/jsm/Addons.js'; //加载gltf模型  备份代码引用
import { GLTFLoader } from 'three/examples/jsm/Addons.js'; //加载gltf模型  备份代码引用
//import { RGBELoader } from 'three/examples/jsm/Addons.js'; //加载hdr贴图
import { OrbitControls } from 'three/examples/jsm/Addons.js';//引入three自带的鼠标控制摄像机包
import  gsap  from 'gsap'; //导入gasp库加载gasp调整贴图的uv移动属性
import { DRACOLoader } from 'three/examples/jsm/Addons.js';//引入支持glb压缩格式文件
//import { any } from "three/tsl";
//import { color } from "three/tsl";
//import { rgbShift } from "three/examples/jsm/tsl/display/RGBShiftNode.js";
//import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';//引入后期处理EffectComposer.js
//import { any } from "three/tsl";
//import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
//import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';//引入后期处理EffectComposer.js
let DM: any;// 新建一个ground变量设置类型为any避免类型报错
let Car: any;//新建一个Car组变量设置类型为any避免类型报错
//let Car1: any;//新建一个Car组变量设置类型为any避免类型报错

const nameToMeshDic:any = {};//创建一个字典用来存储模型名称和模型对象
  
const renderer = new THREE.WebGLRenderer();//引入WebGlRenderer渲染器（renderer就是渲染器的翻译）
renderer.setSize(window.innerWidth,window.innerHeight);//设置渲染窗口长宽
renderer.setPixelRatio(window.devicePixelRatio);//设置渲染屏幕像素比例
renderer.setAnimationLoop(animationLoop);//刷新页面的方法
document.body.appendChild(renderer.domElement);//附加到页面
const scene =new THREE.Scene();//附加到页面
//1.创建WebgGLcubeRenderTarget.
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(1024);//渲染需要6个摄像机所以不要设置太大的分辨率会非常卡
//2.将第一步创建的WebgGlcubeRenderTarget对象作为参数传递给CubeCamera.
const cubeCamera = new THREE.CubeCamera(0.1,800,cubeRenderTarget);
//3.在帧循环中调用第二部创建的CubeCamera对象的update方法，每帧更新渲染结果。
//4.将WebGLCubeRenderTarget对象的texture赋值给环境材质的环境贴图通道：envMap
const camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,800);//设置摄像机参数裁剪面距离
camera.position.set(0,2,5); //设置摄像机空间位置
const controls = new OrbitControls(camera,renderer.domElement);//设置鼠标控制摄像机包引入摄像机
controls.enableDamping = true; // 启用缓动效果
controls.dampingFactor = 0.05; // 设置缓动因子，数值越小缓动越慢

// 限制旋转范围
controls.minPolarAngle = Math.PI / 4; // 最小垂直旋转角度
controls.maxPolarAngle = Math.PI / 2.5; // 最大垂直旋转角度
controls.minAzimuthAngle = -Math.PI / 0; // 最小水平旋转角度（-45度）
controls.maxAzimuthAngle = Math.PI / 0; // 最大水平旋转角度（45度）

// 限制缩放范围
controls.minDistance = 3; // 最小缩放距离
controls.maxDistance = 6; // 最大缩放距离

// 限制平移范围
controls.screenSpacePanning = true; // 启用屏幕空间平移
controls.enablePan = false; // 禁用平移功能
controls.target.set(0, 0, 0); // 设置相机的目标点
controls.update(); // 更新控制器

const gltfLoader = new GLTFLoader();   //设置gltf引入，
const dracoLoader = new  DRACOLoader();   //设置lod变量
dracoLoader.setDecoderPath('libs/draco/');//设置方法以及文件引用路径
gltfLoader.setDRACOLoader(dracoLoader);//传入对象

// 创建平行光
const directionalLight = new THREE.DirectionalLight( 0xffffff , 1); // 白色光，强度为1//#ffffff
directionalLight.position.set(0, 3, 0); // 设置光源位置
directionalLight.castShadow = true; // 允许光源投射阴影

// 设置阴影的属性
directionalLight.shadow.mapSize.width = 1024; // 阴影贴图宽度
directionalLight.shadow.mapSize.height = 1024; // 阴影贴图高度
directionalLight.shadow.camera.near = 0.1; // 阴影相机近裁剪面
directionalLight.shadow.camera.far = 1000; // 阴影相机远裁剪面
directionalLight.shadow.camera.left = -50; // 阴影相机左边界
directionalLight.shadow.camera.right = 50; // 阴影相机右边界
directionalLight.shadow.camera.top = 50; // 阴影相机上边界
directionalLight.shadow.camera.bottom = -50; // 阴影相机下边界

// 将平行光添加到场景中
scene.add(directionalLight);





gltfLoader.load('su77.glb', (gltf) => {
      scene.add(gltf.scene); // 加载模型文件
      console.log(gltf.scene); // 打印模型文件
      gltf.scene.traverse((child: any) => {

       nameToMeshDic[child.name] = child;//创建一个字典用来存储模型名称和模型对象

        //  if (child.isMesh) {

        //     // 创建四边面线框
        //     const edgesGeometry = new THREE.EdgesGeometry(
        //         child.geometry,0 // 设置角度阈值，控制边线生成
               
        //     );
            
        //     const lineMaterial = new THREE.LineBasicMaterial({
        //         color: 0xffffff,      // 线框颜色
        //         linewidth: 1,         // 线宽（注意：在大多数渲染器中实际需要开启抗锯齿才能生效）
        //     });
            
        //     const wireframe = new THREE.LineSegments(edgesGeometry, lineMaterial);
        //     child.add(wireframe);     // 将线框添加到原始网格

        //     // 可选：隐藏原始三角面线框
        //     child.material.wireframe = false;
        //     //child.material.wireframe = true;
        // }


          if (child.type === 'Mesh') {
              child.material.envMap = cubeRenderTarget.texture;//赋值给环境贴图通道envMap
              child.material.side = THREE.DoubleSide;//设置材质双面显示
              child.material.envMapIntensity = 15;//设置材质envMapIntensity属性提高亮度 全局光
              
              
            //   const mesh = new THREE.Mesh(geometry,material);//设置网格渲染
            //   const edgesMaterial = new THREE.  LineBasicMaterial({
            //       color: 0xffffff,
            //   })
            //   const line = new THREE.LineSegments(edges,edgesMaterial);//设置线框渲染
            //   scene.add(line);//添加线框渲染       
          }

                         

    

        
  
          if (child.name === 'XIAOM') {
              child.traverse((item: any) => {            
                  if (item.type === 'Mesh') {

                   
                   

      //    // 创建四边面线框
      //    const edgesGeometry = new THREE.EdgesGeometry(
      //     item.geometry, 0 // 设置角度阈值，控制边线生成
      // );

      // const lineMaterial = new THREE.LineBasicMaterial({
      //     //color:(0xffffff),// 线框颜色
      //     color: new THREE.Color(238, 255, 0),// 使用RGB颜色值设置为白色 RGB颜色值
      //   //rgb(238, 255, 0),
      //   //
      //     linewidth: 1, // 线宽（注意：在大多数渲染器中实际需要开启抗锯齿才能生效）
      // });

      // const wireframe = new THREE.LineSegments(edgesGeometry, lineMaterial);
      // item.add(wireframe); // 将线框添加到原始网格

      // 可选：隐藏原始三角面线框
       //item.material.wireframe = false;
       //item.material.wireframe = true;//设置纯线框渲染

                 
                      // item.material.wireframe = true; // 设置材质为线框渲染
                      // item.material.color = new THREE.Color(0, 100, 255); // 设置线框颜色
                       //
                      
                      
            
                 }
                  //Car = child;
                  
              });
          }
  
         
          // if (child.name  === '前轮' || child.name  === '后轮' ){  //轮子旋转
            
          //   gsap.to(child.rotation,{  //绕轴旋转
          //     x:2 * Math.PI,          //设置绕轴旋转H弧度表示
          //     duration: 1,            //设置旋转时长
          //     repeat: -1,             //设置循环次数，-1表示无限循环
              
          //     //yoyo: true,             //  设置是否循环回滚，true表示循环回滚，false表示不循环回滚
          //     //ease: 'none',   // 设置缓动效果，'none'表示无缓动效果
          //     ease: 'linear',//设置缓动效果，'linear'表示线性缓动效果
          //     //repeatDelay: 0,//设置每次循环的延迟时间，单位为秒，默认为0
          //   });
            
          // }

          if (child.name === '天空流光') {
            child.material.map.anisotropy = 10;//设置贴图的各向异性消除模糊
            child.material.opacity = 1; // 设置材质不透明度（0.0 - 1.0）
            child.material.transparent = true; // 启用透明度
            child.material.map.needsUpdate = true;   // 更新纹理
            
            child.material.emissiveIntensity = 5;//设置材质自发光强度
          }

          if (child.name === 'ground') {
            
            //child.material.envMap = cubeRenderTarget.texture;//赋值给环境贴图通道envMap
    
            // gsap.to(child.material.map.offset, {//设置uv贴图偏移量
            //   x: -1,  // 将uv贴图的x偏移量动画到-1
            //   y: 0,  // 将uv贴图的y偏移量动画到-1
            //   repeat: -1,  // 无限重复动画
            //   ease: 'none',  // 使用线性缓动函数，即匀速变化
            //   duration: 1,  // 动画持续时间为1秒
            //});
          
           
            child.material.side = THREE.DoubleSide;// 设置材质双面显示
            
            child.material.metalness = 1; // 设置金属度为n，可以根据需要调整数值
              child.material.roughness = 0;//设置粗糙度为n，可以根据需要调整数值
              
           
           
         if (child.material.map) {                  // 设置UV平铺
              child.material.map.repeat.set(100, 100); // 将UV重复n次，可以根据需要调整数值
              child.material.opacity = 0.5; // 设置材质不透明度（0.0 - 1.0）
              child.material.transparent = true; // 启用透明度
              //child.material.map.needsUpdate = true;   // 更新纹理
             }
             DM = child;//DM = child;
          
        }
                
          if (child.name === '反射') {
              child.material.metalness = 1; // 设置金属度为n，可以根据需要调整数值
              child.material.roughness = 0;//设置粗糙度为n，可以根据需要调整数值
        
              child.material.side = THREE.DoubleSide;//设置材质双面显示
              child.material.envMapIntensity = 3;//设置材质envMapIntensity属性提高亮度 全局光
              child.material.opacity = 0.2; // 设置材质不透明度（0.0 - 1.0）
              child.material.transparent = true; // 启用透明度 
             
              child.visible = false; // 设置模型可见性
            
            //Car = child;//DM = child;
          }

          
        //   if (child.name === '脏迹') {
        //     // 设置UV平铺
        //     if (child.material.map) {
        //         child.material.map.repeat.set(10, 10); // 将UV重复n次，可以根据需要调整数值
        //         child.material.metalness = 1; // 设置金属度为n，可以根据需要调整数值
        //         child.material.roughness = 0.2;//设置粗糙度为n，可以根据需要调整数值
        //         child.material.map.needsUpdate = true; // 更新纹理
                
        //      }
        // }
  
          if (child.name === 'AO') {
            child.visible = false;//设置不可见
            child.visible = false; // 设置模型可见性
            //Car = child;//DM = child;
          }

         
  
          if (child.name === '车窗') {
                child.material.opacity = 1; // 设置材质不透明度（0.0 - 1.0）
                child.material.transparent = true; // 启用透明度
                child.material.color = new THREE.Color(114/255, 199/255, 255/255); // 设置颜色rgb(114, 199, 255)
                child.material.metalness = 0.5; // 设置金属度为n，可以根据需要调整数值
                child.material.roughness = 0.2;//设置粗糙度为n，可以根据需要调整数值
          }
  
          if (child.name === '图形001') {
            
                child.material.metalness = 1; // 设置金属度为n，可以根据需要调整数值
                child.material.roughness = 0;//设置粗糙度为n，可以根据需要调整数值
                DM = child;
    }
          
          // if (child.name === 'FZ') {
          //     child.traverse((item: any) => {
          //         if (item.type === 'Mesh') {
          //             item.material.envMapIntensity = 100;///设置材质的自发光强度
          //         }
          //     });
          // }
      });
  });

// const rgbELoader = new RGBELoader();    //设置引入hdr
// rgbELoader.load('SKY_3_512.hdr',(skyTexture)=>{
//       scene.background = skyTexture; //设置背景为hdr贴图
//       scene.environment = skyTexture;//设置pbr材质反射hdr贴图
//       skyTexture.mapping = THREE.EquirectangularReflectionMapping;//设置hdr位图为全景图模式
// })


window.addEventListener('mousedown', (e)=>{   //鼠标按下事件
       console.log(e); // 打印鼠标事件对象
       if (e.button === 0){  //按下左键
        gsap.to(camera,{
          fov: 80,//设置相机的fov属性
          duration: 0.3,//设置动画持续时间为1秒
          repeat:0,//设置动画重复次数为1次
          ease: 'power1.inOut',//设置动画缓动函数为先快后慢
          onUpdate: ()=>{//更新相机投影矩阵
            camera.updateProjectionMatrix();//更新相机投影矩阵
          }
        });
          const 天空流光 = nameToMeshDic['天空流光'];//天空流光
      
          gsap.to(天空流光.material.map.offset, {//设置uv贴图偏移量
            x: -1,  // 将uv贴图的x偏移量动画到-1
            y: 0,  // 将uv贴图的y偏移量动画到-1
            repeat: -1,  // 无限重复动画
            ease: 'none',  // 使用线性缓动函数，即匀速变化
            duration: 3,  // 动画持续时间为秒
          });

          const ground = nameToMeshDic['ground'];//ground
      
          gsap.to(ground.material.map.offset, {//设置uv贴图偏移量
            x: -1,  // 将uv贴图的x偏移量动画到-1
            y: 0,  // 将uv贴图的y偏移量动画到-1
            repeat: -1,  // 无限重复动画
            ease: 'none',  // 使用线性缓动函数，即匀速变化
            duration: 3,  // 动画持续时间为秒
          });

          const 前轮 = nameToMeshDic['前轮'];//前轮
          gsap.to(前轮.rotation,{  //绕轴旋转
            x:2 * Math.PI,          //设置绕轴旋转H弧度表示
            duration: 1,            //设置旋转时长
            repeat: -1,             //设置循环次数，-1表示无限循环          
            ease: 'linear',//设置缓动效果，'linear'表示线性缓动效果   
          });

          const 后轮 = nameToMeshDic['后轮'];//后轮
          gsap.to(后轮.rotation,{  //绕轴旋转
            x:2 * Math.PI,          //设置绕轴旋转H弧度表示
            duration: 1,            //设置旋转时长
            repeat: -1,             //设置循环次数，-1表示无限循环          
            ease: 'linear',//设置缓动效果，'linear'表示线性缓动效果   
          });
       }
       
});

window.addEventListener('mouseup', (e)=>{   //鼠标抬起事件
  console.log(e); // 打印鼠标事件对象
  if (e.button === 0){//按下左键
   gsap.to(camera,{
     fov: 60,//设置相机的fov属性
     duration: 0.3,//设置动画持续时间为1秒
     repeat:0,//设置动画重复次数为1次
     ease: 'power1.inOut',//设置动画缓动函数为无
     onUpdate: ()=>{//更新相机投影矩阵
       camera.updateProjectionMatrix();//更新相机投影矩阵
     }
   });
  }
  //if (e.button === 1)//按下中键
  //if (e.button === 2)//按下右键
  //if (e.button === 3)//按下四键
});

//函数动画循环，帧循环
function animationLoop(){
      controls.update();//调用方法
      if  (Car){
        Car.visible = false;//先设置隐藏Car属性
        //Car1.visible = false;//先设置隐藏Car属性
        cubeCamera.position.copy(camera.position);    //对象摄像机的位置复制给当前屏幕摄像机
        cubeCamera.position.y = -cubeCamera.position.y;   // 对象摄像机的y值取反
        // // cubeCamera.position.x = -cubeCamera.position.x;   // 对象摄像机的y值取反
        // // cubeCamera.position.z = -cubeCamera.position.z;   // 对象摄像机的y值取反
        cubeCamera.update(renderer,scene)//摄像机更新渲染器参数，和场景参数
        Car.visible = true;//恢复地面属性
      }
      if  (DM){
            DM.visible = false; //先设置隐藏地面属性
            //Car.visible = false;//先设置隐藏Car属性
            //Car1.visible = false;//先设置隐藏Car属性
            cubeCamera.position.copy(camera.position);    //对象摄像机的位置复制给当前屏幕摄像机
            cubeCamera.position.y = -cubeCamera.position.y;   // 对象摄像机的y值取反
            // // cubeCamera.position.x = -cubeCamera.position.x;   // 对象摄像机的y值取反
            // // cubeCamera.position.z = -cubeCamera.position.z;   // 对象摄像机的y值取反
            cubeCamera.update(renderer,scene)//摄像机更新渲染器参数，和场景参数
            DM.visible = true;//恢复地面属性
            //Car.visible = true;//恢复地面属性
           // Car1.visible = true;//先设置隐藏Car属性
      }
    //   composer.render(); // 使用 EffectComposer 渲染
      renderer.render(scene,camera);   //函数调用不停的更新画面
      //composer.render(); // 使用 EffectComposer 渲染
      
}

